﻿using System;
using System.Diagnostics;
using System.Globalization;

namespace LuaVM.Core.Builtin
{
	class OSFuncs
	{
		LuaEnv m_lua = null;

		public OSFuncs(LuaEnv lua)
		{
			m_lua = lua;
			lua.RegisterFunction<OSFuncs>(this, "Exit", "os.exit");
			lua.RegisterFunction<OSFuncs>("Execute", "os.execute");
			lua.RegisterFunction<OSFuncs>(this, "Date", "os.date");
		}

		// os.exit()
		public void Exit()
		{			
			throw new Exception("os.exit() called.");
		}

		// os.execute()
		public static int Execute(string fileName, string arguments = null)
		{
			Process proc = Process.Start(fileName, arguments);
			return proc.Id;
		}

		public object Date(string format = null)
		{
			format = (format ?? "").Trim();
			
			DateTime now = DateTime.Now;
			if (format == "")
			{
				return now.ToString();
			}

			if (format == "*t")
			{
				LuaTable table = m_lua.NewTable();
				table["year"] = now.Year;
				table["month"] = now.Month;
				table["day"] = now.Day;
				table["hour"] = now.Hour;
				table["min"] = now.Minute;
				table["sec"] = now.Second;
				table["wday"] = (int)now.DayOfWeek + 1;
				table["yday"] = now.DayOfYear;
				table["isdst"] = now.IsDaylightSavingTime();
				return table.Table;
			}

			format = format.Replace("%%", "#MY_DBL_P#");
			format = format.Replace("%a", "ddd");
			format = format.Replace("%A", "dddd");
			format = format.Replace("%b", "MMM");
			format = format.Replace("%B", "MMMM");

			format = format.Replace("%d", "dd");
			format = format.Replace("%H", "HH");
			format = format.Replace("%I", "hh");
			format = format.Replace("%j", string.Format("{0:D3}", now.DayOfYear));
			format = format.Replace("%m", "MM");
			format = format.Replace("%M", "mm");
			format = format.Replace("%p", "t\\M");
			format = format.Replace("%S", "ss");
			format = format.Replace("%U", string.Format("{0:D2}", GetWeekOfYear(now, DayOfWeek.Sunday))); // 一年中的第几周，以第一个星期日作为第一周的第一天（00-53）
			format = format.Replace("%w", string.Format("{0}", (int)now.DayOfWeek + 1));
			format = format.Replace("%W", string.Format("{0:D2}", GetWeekOfYear(now, DayOfWeek.Monday))); // 一年中的第几周，以第一个星期一作为第一周的第一天（00-53）
			format = format.Replace("%x", "dd/MM/yy");
			format = format.Replace("%X", "HH:mm:ss");
			format = format.Replace("%y", "yy");
			format = format.Replace("%Y", "yyyy");
			//format = format.Replace("%Z", ""); // 时区的名称或缩写 (CDT)

			format = format.Replace("%c", now.ToString());
			format = format.Replace("#MY_DBL_P#", "%%");
			return now.ToString(format);
		}

		private static int GetWeekOfYear(DateTime dt, DayOfWeek dow)
		{
			GregorianCalendar gc = new GregorianCalendar();
			int weekOfYear = gc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, dow);
			return weekOfYear;
		}
	}
}
